package db

import (
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"log"
	"reflect"
)

var (
	url        = "mongodb://manhuatai:manhuatai2018123456@118.31.78.77:27017/manhuatai"
	mgoSession *mgo.Session
	dataBase   = "manhuatai"
)

func getSession() *mgo.Session {
	if mgoSession == nil {
		var err error
		mgoSession, err = mgo.Dial(url)
		if err != nil {
			panic(err)
		}
	}
	//最大连接池默认为4096
	return mgoSession.Clone()
}

func witchCollection(collection string, s func(*mgo.Collection) error) error {
	session := getSession()
	defer session.Close()
	c := session.DB(dataBase).C(collection)
	return s(c)
}

// 执行查询，此方法可拆分做为公共方法
func SearchData(res interface{}, m Model, query bson.M, sort string, fields bson.M, skip int, limit int) (err error) {
	exop := func(c *mgo.Collection) error {
		return c.Find(query).Sort(sort).Select(fields).Skip(skip).Limit(limit).All(res)
	}
	err = witchCollection(m.TableName(), exop)
	return
}

// 获取一条记录通过 objectid
func GetDataById(m Model, id string) (err error) {
	objid := bson.ObjectIdHex(id)
	query := func(c *mgo.Collection) error {
		return c.FindId(objid).One(m)
	}
	err = witchCollection(m.TableName(), query)
	return
}

// 获取一条数据
func GetOneData(m Model, query bson.M) (err error) {
	exop := func(c *mgo.Collection) error {
		return c.Find(query).One(m)
	}
	err = witchCollection(m.TableName(), exop)
	return
}

// 获取数据总条数
func DataTotal(m Model, query bson.M) (count int) {
	exop := func(c *mgo.Collection) (err error) {
		count, err = c.Find(query).Count()
		return err
	}
	err := witchCollection(m.TableName(), exop)
	if err != nil {
		log.Printf("err:%v", err)
		return
	}
	return
}

//AddData 数据添加
func AddData(m Model) (err error) {
	// 反射修改字段
	p := reflect.ValueOf(m).Elem()
	p.FieldByName("Id").Set(reflect.ValueOf(bson.NewObjectId()))

	query := func(c *mgo.Collection) error {
		return c.Insert(&m)
	}
	err = witchCollection(m.TableName(), query)
	return
}

// 获取所有的person数据
func GetTotalData(res interface{}, m Model, query bson.M) (err error) {
	exop := func(c *mgo.Collection) error {
		return c.Find(query).All(res)
	}
	if err = witchCollection(m.TableName(), exop); err != nil {
		log.Printf("err:%v", err)
		return
	}
	return
}

// UpdateData 更新数据
func UpdateData(m Model, query bson.M, change bson.M) string {
	exop := func(c *mgo.Collection) error {
		return c.Update(query, change)
	}
	err := witchCollection(m.TableName(), exop)
	if err != nil {
		log.Printf("err:%v", err)
		return "true"
	}
	return "false"
}
